#include "actions.hpp"



void opNonCalc(ConteneurCode &conteneurCode,
		const string &operateur, Operande &retour, Operande &operandeG,
		Operande &operandeD)
{
	// Creation d'un temporaire.
    stringstream out;
    out << tempoCourant;
    tableId->add("__Temp000"+out.str());
    tableSM.getCurrentTableSymb()->Ajout(new SymboleTemp(),
			tableId->getNum("__Temp000"+out.str()));
    tempoCourant ++;

	//cout << "AJOUT TEMPO." << endl;

	// Operande pour le resultat de l'instruction.
    Operande operandeTempo = new Operande(
			tableId->getNum("__Temp000"+out.str()),
			new Valeur(),
			false);

	//cout << "NEW OPERANDE." << endl;

	// Creation de l'instruction.
    Instruction* nouvelleInstruction = new Instruction(
			operateur, operandeTempo, operandeG, operandeD, *tableId);
    conteneurCode.ajouterInstruct(nouvelleInstruction);
    retour = operandeTempo;
}

void opNonCalc(ConteneurCode &conteneurCode,
		const string &operateur, Operande &retour, Operande &operandeG)
{
	// Creation d'un temporaire.
    stringstream out;
    out << tempoCourant;
    tableId->add("__Temp000"+out.str());
    tableSM.getCurrentTableSymb()->Ajout(new SymboleTemp(),
			tableId->getNum("__Temp000"+out.str()));
    tempoCourant ++;

	// Operande pour le resultat de l'instruction.
    Operande operandeTempo = new Operande(
			tableId->getNum("__Temp000"+out.str()),
			new Valeur(),
			false);

	// Creation de l'instruction.
    if(&operandeG != NULL)
    {
        Instruction* nouvelleInstruction = new Instruction(
				operateur, operandeTempo, operandeG, *tableId);
        conteneurCode.ajouterInstruct(nouvelleInstruction);
        retour = operandeTempo;
    }
}

void calculAdd(ConteneurCode &conteneurCode,
		const string &operateur, Operande &retour, Operande &operandeG,
		Operande &operandeD)
{
	cout << "TODO" << endl;
	/*
	if(opG.getValeur()->getT()->getClass() == "integer")
            outG << opG.getValeur()->getValeurInteger();
        else if(opG.getValeur()->getT()->getClass() == "real")
            outG << opG.getValeur()->getValeurFloat();
        else if(opG.getValeur()->getT()->getClass() == "string")
            outG << opG.getValeur()->getValeurString();
		else {
			// Erreur ?
		}
	*/

}

void calculMath(ConteneurCode &conteneurCode,
		const string &operateur, Operande &retour, Operande &operandeG)
{
	cout << "TODO" << endl;
}

void calculMath(ConteneurCode &conteneurCode,
		const string &operateur, Operande &retour, Operande &operandeG,
		Operande &operandeD)
{
	if(operateur.compare("ADD")) {
		calculAdd(conteneurCode, operateur, retour, operandeG,
				operandeD);
	}
	else if(operateur.compare("SUB")) {
	}
	else if(operateur.compare("MUL")) {
	}
	else if(operateur.compare("DIV")) {
	}
	else if(operateur.compare("MOD")) {
	}
	else {
		cerr << "UNKNOWN OPERATION." << endl;
	}

}

void actionMath(ConteneurCode &conteneurCode,
		const string &operateur, Operande &retour, Operande &operandeG,
		Operande &operandeD)
{
    if((&operandeG != NULL) && (&operandeD !=NULL))
    {
		// Jamais possible (a corriger).
		if(operandeG.EstCalculee() && operandeD.EstCalculee()) {
			calculMath(conteneurCode, operateur, retour, operandeG,
				operandeD);
		}
		else {
			//cout << "non calc." << endl;
			opNonCalc(conteneurCode, operateur, retour, operandeG,
					operandeD);
		}
    }
	//cout << "FIN ACTIONMATH." << endl;
}

void actionMath(ConteneurCode &conteneurCode,
		const string &operateur, Operande &retour, Operande &operandeG)
{
   if((&operandeG != NULL))
    {
		// Jamais possible (a corriger).
		if(operandeG.EstCalculee()) {
			calculMath(conteneurCode, operateur, retour, operandeG);
		}
		else {
			//cout << "non calc." << endl;
			opNonCalc(conteneurCode, operateur, retour, operandeG);
		}
    }
}

void actionBool(ConteneurCode &conteneurCode,
		const string &operateur, Operande &retour, Operande &operandeG,
		Operande &operandeD)
{
    if((&operandeG != NULL) && (&operandeD !=NULL))
    {
		// Jamais possible (a corriger).
		if(operandeG.EstCalculee() && operandeD.EstCalculee()) {
			//calculBool(conteneurCode, operateur, retour, operandeG,
			//	operandeD);
		}
		else {
			//cout << "non calc." << endl;
			opNonCalc(conteneurCode, operateur, retour, operandeG,
					operandeD);
		}
    }
	//cout << "FIN ACTIONMATH." << endl;
}

void actionBool(ConteneurCode &conteneurCode,
		const string &operateur, Operande &retour, Operande &operandeG)
{
   if((&operandeG != NULL))
    {
		// Jamais possible (a corriger).
		if(operandeG.EstCalculee()) {
			calculMath(conteneurCode, operateur, retour, operandeG);
		}
		else {
			//cout << "non calc." << endl;
			opNonCalc(conteneurCode, operateur, retour, operandeG);
		}
    }
}


